﻿using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using Elderos.Utils;

namespace TreeBuilder
{
    /// <summary>
    /// Interaction logic for IndexBlock.xaml
    /// </summary>
    public partial class IndexBlock : UserControl, IAdorner, IPrintable
    {
        //It's a very, very annoying margin, which can't be removed
        private double ElementHorizontalMargin { get { return 4; } }
        private double ElementVerticalMargin { get { return Element.ActualHeight/4; } }
        private double VerticalMargin { get { return this.ActualHeight/6; } }


        public IndexBlock()
        {
            InitializeComponent();
            Panel.SetZIndex(this, 3);
        }

        #region Implementation of IAdorner

        public TreeNode Element { get; set; }

        public void RefreshPoints()
        {
            if (Element == null) return;

            double x = Element.RightCenter.X - ElementHorizontalMargin;

            double y;

            switch (IndexType)
            {
                case IndexTypes.Upper:
                    y = Math.Min(Element.Center.Y - this.ActualHeight / 2 + ElementVerticalMargin, Element.Center.Y - VerticalMargin);
                    break;
                case IndexTypes.Lower:
                    y = Math.Max(Element.BottomCenter.Y - this.ActualHeight / 2 - ElementVerticalMargin, Element.RightCenter.Y - VerticalMargin);
                    break;
                default:
                    y = Element.RightCenter.Y;
                    break;
            }

            Canvas.SetLeft(this, x);
            Canvas.SetTop(this, y);
        }

        public IndexTypes IndexType { get; set; }

        #endregion

        #region Implementation of IPrintable

        public bool IsBeingPrinted
        {
            get { return (bool)GetValue(IsBeingPrintedProperty); }
            set { SetValue(IsBeingPrintedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsBeingPrinted.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsBeingPrintedProperty =
            DependencyProperty.Register("IsBeingPrinted", typeof(bool), typeof(IndexBlock), new UIPropertyMetadata(false));

        

        #endregion

        #region Implementation of IXmlSerializable

        /// <summary>
        /// This method is reserved and should not be used. When implementing the IXmlSerializable interface, you should return null (Nothing in Visual Basic) from this method, and instead, if specifying a custom schema is required, apply the <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute"/> to the class.
        /// </summary>
        /// <returns>
        /// An <see cref="T:System.Xml.Schema.XmlSchema"/> that describes the XML representation of the object that is produced by the <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)"/> method and consumed by the <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)"/> method.
        /// </returns>
        public XmlSchema GetSchema()
        {
            return null;
        }

        /// <summary>
        /// Generates an object from its XML representation.
        /// </summary>
        /// <param name="reader">The <see cref="T:System.Xml.XmlReader"/> stream from which the object is deserialized. </param>
        public void ReadXml(XmlReader reader)
        {
            XDocument doc = XDocument.Load(reader);

            var root = doc.Root;

            TextBlock.Text = root.Element("Text").Value;
            TextBlock.FontFamily = (FontFamily)XamlReader.Parse(root.Element("FontFamily").Value);
            TextBlock.FontSize = double.Parse(root.Element("FontSize").Value.Replace(",", "."), CultureInfo.InvariantCulture);
            TextBlock.FontStretch = (FontStretch)XamlReader.Parse(root.Element("FontStretch").Value);
            TextBlock.FontStyle = (FontStyle)XamlReader.Parse(root.Element("FontStyle").Value);
            TextBlock.FontWeight = (FontWeight)XamlReader.Parse(root.Element("FontWeight").Value);
            TextBlock.TextDecorations = (TextDecorationCollection)XamlReader.Parse(root.Element("TextDecorations").Value);
            TextBlock.Foreground = (Brush)XamlReader.Parse(root.Element("Foreground").Value);

            IndexType = (IndexTypes) int.Parse(root.Element("IndexType").Value);
        }

        /// <summary>
        /// Converts an object into its XML representation.
        /// </summary>
        /// <param name="writer">The <see cref="T:System.Xml.XmlWriter"/> stream to which the object is serialized. </param>
        public void WriteXml(XmlWriter writer)
        {
            writer.WriteRaw("<Text xml:space=\"preserve\">"+TextBlock.Text+"</Text>");
            writer.WriteElementString("FontFamily", XamlWriter.Save(TextBlock.FontFamily));
            writer.WriteElementString("FontSize", TextBlock.FontSize.ToString());
            writer.WriteElementString("FontStretch", XamlWriter.Save(TextBlock.FontStretch));
            writer.WriteElementString("FontStyle", XamlWriter.Save(TextBlock.FontStyle));
            writer.WriteElementString("FontWeight", XamlWriter.Save(TextBlock.FontWeight));
            writer.WriteElementString("TextDecorations", XamlWriter.Save(TextBlock.TextDecorations));
            writer.WriteElementString("Foreground", XamlWriter.Save(TextBlock.Foreground));

            writer.WriteElementString("IndexType", ((int) IndexType).ToString());
        }

        #endregion
    }
}
